﻿/*
Copyright © 2010 François Karman

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

See <license.txt> for the complete license of the software.
*/

using System;
using System.Collections;
using System.Collections.Generic;

namespace MSBuild.Mercurial.CodePlex
{
    /// <summary>
    /// Implements a sorted collection of <see cref="PropertyDocumentation"/>.
    /// </summary>
    public class PropertyCollection : ICollection<PropertyDocumentation>, ICollection
    {
        /// <summary>
        /// The encapsulated sorted list.
        /// </summary>
        private SortedList<string, PropertyDocumentation> encapsulated;

        /// <summary>
        /// Initializes a new instance of the PropertyCollection class.
        /// </summary>
        public PropertyCollection()
        {
            this.encapsulated = new SortedList<string, PropertyDocumentation>();
        }

        /// <summary>
        /// Gets the number of element in the collection.
        /// </summary>
        public int Count
        {
            get { return this.encapsulated.Count; }
        }

        /// <summary>
        /// Gets a value indicating whether the collection can be
        /// modified.
        /// </summary>
        /// <remarks>
        /// This property always return <c>true</c>.
        /// </remarks>
        public bool IsReadOnly
        {
            get { return true; }
        }

        /// <summary>
        /// Gets a value indicating whether the collection is thread-safe.
        /// </summary>
        public bool IsSynchronized
        {
            get { return ((System.Collections.ICollection)this.encapsulated).IsSynchronized; }
        }

        /// <summary>
        /// Gets the synchronization object of the collection.
        /// </summary>
        public object SyncRoot
        {
            get { return ((System.Collections.ICollection)this.encapsulated).SyncRoot; }
        }

        /// <summary>
        /// Accessor based on the name of the manipulated task.
        /// </summary>
        /// <param name="name">
        /// The name of the task.
        /// </param>
        /// <returns>
        /// The task associated with <paramref name="name"/>.
        /// </returns>
        public PropertyDocumentation this[string name]
        {
            get { return this.encapsulated[name]; }
            set { this.encapsulated[name] = value; }
        }

        /// <summary>
        /// Accessor based on the index of the task in the collection.
        /// </summary>
        /// <param name="index">
        /// The index of the task in the collection.
        /// </param>
        /// <returns>
        /// The task associated with <paramref name="index"/>.
        /// </returns>
        public PropertyDocumentation this[int index]
        {
            get { return this.encapsulated.Values[index]; }
            set { this.encapsulated.Values[index] = value; }
        }

        /// <summary>
        /// Adds a new property to the collection.
        /// </summary>
        /// <param name="item">
        /// The property to add.
        /// </param>
        public void Add(PropertyDocumentation item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            this.encapsulated.Add(item.Name, item);
        }

        /// <summary>
        /// Clears all the values of the collection.
        /// </summary>
        public void Clear()
        {
            this.encapsulated.Clear();
        }

        /// <summary>
        /// Checks if the collection contains a specific element.
        /// </summary>
        /// <param name="item">
        /// The searched item.
        /// </param>
        /// <returns>
        /// <c>true</c> if <paramref name="item"/> is in the collection,
        /// <c>false</c> otherwise.
        /// </returns>
        public bool Contains(PropertyDocumentation item)
        {
            return this.encapsulated.ContainsValue(item);
        }

        /// <summary>
        /// Copies all the values in an array.
        /// </summary>
        /// <param name="array">
        /// The destination array.
        /// </param>
        /// <param name="arrayIndex">
        /// The start position for the copy in the array.
        /// </param>
        public void CopyTo(PropertyDocumentation[] array, int arrayIndex)
        {
            this.encapsulated.Values.CopyTo(array, arrayIndex);
        }

        /// <summary>
        /// Removes an element from the collection.
        /// </summary>
        /// <param name="item">
        /// The element to remove.
        /// </param>
        /// <returns>
        /// <c>true</c> if the element has been removed.
        /// </returns>
        public bool Remove(PropertyDocumentation item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            return this.encapsulated.Remove(item.Name);
        }

        /// <summary>
        /// Gets an enumerator for all the values of the collection.
        /// </summary>
        /// <returns>
        /// An enumerator associated with the collection.
        /// </returns>
        public IEnumerator<PropertyDocumentation> GetEnumerator()
        {
            return this.encapsulated.Values.GetEnumerator();
        }

        /// <summary>
        /// Gets an enumerator for all the values of the collection.
        /// </summary>
        /// <returns>
        /// An enumerator associated with the collection.
        /// </returns>
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return ((System.Collections.IEnumerable)this.encapsulated.Values).GetEnumerator();
        }

        /// <summary>
        /// Copies all the values in an array.
        /// </summary>
        /// <param name="array">
        /// The destination array.
        /// </param>
        /// <param name="index">
        /// The start position for the copy in the array.
        /// </param>
        public void CopyTo(Array array, int index)
        {
            ((System.Collections.ICollection)this.encapsulated.Values).CopyTo(array, index);
        }
    }
}
